<script setup lang="ts">
import {ref, computed, onMounted} from 'vue'
import {NCard, NTag, NSpace, NGradientText, NButton, NModal, NRate, NInput, NSelect, useMessage, NMessageProvider} from 'naive-ui'
import {
  modList, 
  modListWithTag, 
  markUsed, 
  cancelUsed, 
  markScore, 
  cancelScore,
  ModListOrderBy,
  type ModListResDTO,
  type ModListReqDTO,
  type ModMarkScoreResDTO,
  type ModMarkUsedResDTO
} from "@/apis/mod_api.ts";
import {type CommonPageReqDTO, type CommonResDTO, type CommonPageResDTO} from "@/apis/config.ts";

// 状态管理
const projects = ref<ModListResDTO[]>([]);
const loading = ref(false);
const currentPage = ref(1);
const pageSize = ref(10);
const totalCount = ref(0);
const searchQuery = ref('');
const selectedTag = ref('');
const showRatingModal = ref(false);
const currentProject = ref<ModListResDTO | null>(null);
const ratingValue = ref(0);
const ratingComment = ref('');

// 排序选项
const sortBy = ref('scoreAvg'); // 'scoreAvg' | 'usedAmount'
const sortOrder = ref('desc'); // 'asc' | 'desc'

// 获取排序方式
const getOrderBy = computed(() => {
  if (sortBy.value === 'scoreAvg') {
    return sortOrder.value === 'desc' ? ModListOrderBy.SCORE_DESC : ModListOrderBy.SCORE_ASC;
  } else {
    return sortOrder.value === 'desc' ? ModListOrderBy.USED_DESC : ModListOrderBy.USED_ASC;
  }
});

// 获取包列表
const getProjects = async () => {
  loading.value = true;
  try {
    let response: CommonResDTO<CommonPageResDTO<ModListResDTO>>;
    
    if (selectedTag.value) {
      // 按标签查询
      response = await modListWithTag(selectedTag.value, {
        page: currentPage.value,
        pageSize: pageSize.value,
        data: {
          keyword: searchQuery.value,
          orderBy: getOrderBy.value
        }
      });
    } else {
      // 按关键词查询
      response = await modList({
        page: currentPage.value,
        pageSize: pageSize.value,
        data: {
          keyword: searchQuery.value,
          orderBy: getOrderBy.value
        }
      });
    }

    if (response.code === 0 && response.data) {
      projects.value = response.data.list;
      totalCount.value = response.data.totalCount;
    } else {
      window.alert(response.message || '获取项目列表失败');
    }
  } catch (error) {
    console.error('Failed to fetch projects:', error);
    window.alert('获取项目列表失败');
  } finally {
    loading.value = false;
  }
};

// 标记使用/取消使用
const handleUse = async (project: ModListResDTO) => {
  try {
    let response: CommonResDTO<ModMarkUsedResDTO>;
    
    if (!project.usedInfo.myUsed) {
      // 标记为已使用
      response = await markUsed(project.modPackageName);
    } else {
      // 标记为未使用
      response = await cancelUsed(project.modPackageName);
    }
    
    if (response.code === 0 && response.data) {
      project.usedInfo.myUsed = response.data.myUsed;
      project.usedInfo.usedAmount = response.data.usedAmount;
      window.alert(project.usedInfo.myUsed ? '已标记为使用' : '已取消使用标记');
    } else {
      window.alert(response.message || '操作失败');
    }
  } catch (error) {
    console.error('Failed to update usage status:', error);
    window.alert('操作失败');
  }
};

// 打开评分对话框
const openRatingModal = (project: ModListResDTO) => {
  currentProject.value = project;
  ratingValue.value = project.scoreInfo.myScore || 0;
  ratingComment.value = '';
  showRatingModal.value = true;
};

// 提交评分
const submitRating = async () => {
  if (!currentProject.value || ratingValue.value === 0) return;

  try {
    // 提交评分
    const response = await markScore(currentProject.value.modPackageName, ratingValue.value);
    
    if (response.code === 0 && response.data) {
      currentProject.value.scoreInfo.myScore = response.data.myScore;
      currentProject.value.scoreInfo.scoreAvg = response.data.scoreAvg;
      showRatingModal.value = false;
      window.alert('评分成功');
    } else {
      window.alert(response.message || '评分失败');
    }
  } catch (error) {
    console.error('Failed to submit rating:', error);
    window.alert('评分失败');
  }
};

// 清除评分
const clearRating = async (project: ModListResDTO) => {
  try {
    const response = await cancelScore(project.modPackageName);
    
    if (response.code === 0 && response.data) {
      project.scoreInfo.myScore = response.data.myScore;
      project.scoreInfo.scoreAvg = response.data.scoreAvg;
      window.alert('已清除评分');
    } else {
      window.alert(response.message || '清除评分失败');
    }
  } catch (error) {
    console.error('Failed to clear rating:', error);
    window.alert('清除评分失败');
  }
};

// 获取项目源码链接
const getRepoUrl = (project: ModListResDTO) => {
  return project.modHomePage || '#';
};

// 获取状态颜色
const getStatusColor = (score: number) => {
  if (score >= 8) {
    return {color: '#48bb78', bgColor: 'rgba(72, 187, 120, 0.1)'};
  } else if (score >= 6) {
    return {color: '#4299e1', bgColor: 'rgba(66, 153, 225, 0.1)'};
  } else if (score >= 4) {
    return {color: '#ecc94b', bgColor: 'rgba(236, 201, 75, 0.1)'};
  } else {
    return {color: '#a0aec0', bgColor: 'rgba(160, 174, 192, 0.1)'};
  }
};

// 监听搜索和排序变化
const handleSearch = () => {
  currentPage.value = 1;
  getProjects();
};

// 页面加载时获取数据
onMounted(() => {
  getProjects();
});
</script>

<template>
  <NMessageProvider>
    <main class="projects-page">
      <section class="projects-hero">
        <div class="hero-content">
          <h1>
            <NGradientText :gradient="{ from: '#ffffff', to: '#e0e0e0' }">
              开源项目
            </NGradientText>
          </h1>
          <p class="hero-description">探索社区开发的优秀项目，欢迎贡献和使用</p>
        </div>
      </section>

      <section class="projects-content">
        <div class="content-wrapper">
          <div class="filters">
            <div class="search-box">
              <input
                  type="text"
                  v-model="searchQuery"
                  placeholder="搜索项目..."
                  class="search-input"
                  @keyup.enter="handleSearch"
              >
            </div>
            <div class="filter-options">
              <NSelect
                  v-model:value="sortBy"
                  :options="[
                  { label: '评分优先', value: 'scoreAvg' },
                  { label: '使用量优先', value: 'usedAmount' }
                ]"
                  class="sort-select"
                  @update:value="handleSearch"
              />
              <NSelect
                  v-model:value="sortOrder"
                  :options="[
                  { label: '降序', value: 'desc' },
                  { label: '升序', value: 'asc' }
                ]"
                  class="sort-select"
                  @update:value="handleSearch"
              />
              <NButton
                  type="primary"
                  @click="handleSearch"
                  :disabled="loading"
              >
                搜索
              </NButton>
            </div>
          </div>

          <div class="projects-grid">
            <NCard
                v-for="project in projects"
                :key="project.modInfoId"
                class="project-card"
                :bordered="false"
                :style="{
                background: 'linear-gradient(165deg, rgba(40, 40, 45, 0.8), rgba(25, 25, 30, 0.9))',
                border: '1px solid rgba(123, 130, 255, 0.08)',
                backdropFilter: 'blur(12px)'
              }"
            >
              <div class="project-header">
                <NTag
                    v-for="tag in project.modTagList"
                    :key="tag"
                    :bordered="false"
                    :style="{
                    background: 'rgba(123, 130, 255, 0.1)',
                    color: '#7b82ff',
                    padding: '2px 12px'
                  }"
                >
                  {{ tag }}
                </NTag>
              </div>
              <h3>{{ project.modName }}</h3>
              <p class="project-description">{{ project.modDescription }}</p>
              <div class="project-stats">
                <div class="stat-item">
                  <span class="stat-label">使用量</span>
                  <span class="stat-value">{{ project.usedInfo.usedAmount }}</span>
                </div>
                <div class="stat-item">
                  <span class="stat-label">评分</span>
                  <div class="rating-display">
                    <NRate :value="project.scoreInfo.scoreAvg / 2" readonly allow-half size="small"/>
                    <span class="rating-value">{{ project.scoreInfo.scoreAvg.toFixed(1) }}</span>
                  </div>
                </div>
              </div>

              <div class="project-actions">
                <NButton
                    :type="project.usedInfo.myUsed ? 'default' : 'primary'"
                    size="small"
                    @click="handleUse(project)"
                    :style="{
                    background: project.usedInfo.myUsed ? 'rgba(123, 130, 255, 0.1)' : 'linear-gradient(135deg, #7b82ff 0%, #9ba0ff 100%)',
                    border: project.usedInfo.myUsed ? '1px solid rgba(123, 130, 255, 0.2)' : 'none',
                    color: project.usedInfo.myUsed ? '#7b82ff' : '#ffffff',
                    cursor: 'pointer',
                    padding: '6px 12px',
                    fontWeight: '500',
                    transition: 'all 0.3s ease',
                    display: 'inline-flex',
                    alignItems: 'center',
                    gap: '4px'
                  }"
                    :hover-style="{
                    background: project.usedInfo.myUsed ? 'rgba(123, 130, 255, 0.15)' : 'linear-gradient(135deg, #8a91ff 0%, #a5a9ff 100%)',
                    transform: 'translateY(-2px)',
                    boxShadow: project.usedInfo.myUsed ? '0 4px 12px rgba(123, 130, 255, 0.15)' : '0 4px 12px rgba(123, 130, 255, 0.3)'
                  }"
                >
                  {{ project.usedInfo.myUsed ? '✓ 已使用' : '我用过' }}
                </NButton>
                <NButton
                    type="primary"
                    size="small"
                    @click="openRatingModal(project)"
                    ghost
                >
                  {{ project.scoreInfo.myScore ? '修改评分' : '评分' }}
                </NButton>
              </div>

              <div class="project-meta">
                <div class="meta-info">
                  <div class="meta-item" v-if="project.scoreInfo.myScore">
                    <span class="meta-label">我的评分</span>
                    <span>{{ project.scoreInfo.myScore }}</span>
                  </div>
                  <div class="meta-item">
                    <span class="meta-label">包名</span>
                    <span>{{ project.modPackageName }}</span>
                  </div>
                </div>
                <NButton
                    size="small"
                    tag="a"
                    :href="getRepoUrl(project)"
                    target="_blank"
                    :style="{
                    background: 'linear-gradient(135deg, #7b82ff 0%, #9ba0ff 100%)',
                    border: 'none',
                    color: '#ffffff'
                  }"
                >
                  查看项目
                </NButton>
              </div>
            </NCard>
          </div>
        </div>
      </section>

      <!-- 评分对话框 -->
      <NModal
          v-model:show="showRatingModal"
          title="项目评分"
          preset="card"
          style="max-width: 600px"
      >
        <div v-if="currentProject" class="rating-modal">
          <h3>{{ currentProject.modName }}</h3>
          <div class="rating-form">
            <div class="rating-field">
              <label>评分 (1-10)</label>
              <NRate v-model:value="ratingValue" :count="10" :allow-half="false"/>
            </div>
            <div class="rating-field">
              <label>评价意见（可选）</label>
              <NInput
                  v-model:value="ratingComment"
                  type="textarea"
                  placeholder="分享你的使用体验..."
                  :rows="4"
              />
            </div>
          </div>
          <div class="modal-footer">
            <NButton @click="showRatingModal = false">取消</NButton>
            <NButton
                type="primary"
                @click="submitRating"
                :disabled="ratingValue === 0"
            >
              提交评分
            </NButton>
            <NButton
                v-if="currentProject.scoreInfo.myScore"
                @click="clearRating(currentProject)"
            >
              清除评分
            </NButton>
          </div>
        </div>
      </NModal>
    </main>
  </NMessageProvider>
</template>

<style scoped>
.projects-page {
  width: 100%;
}

.projects-hero {
  padding: 8rem 2rem 4rem;
  background: linear-gradient(135deg, #1a1a1a 0%, #2c2c2c 100%);
  text-align: center;
  position: relative;
  overflow: hidden;
}

.projects-hero::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: radial-gradient(circle at center, rgba(123, 130, 255, 0.1) 0%, transparent 70%);
  pointer-events: none;
}

.hero-content {
  max-width: 800px;
  margin: 0 auto;
  position: relative;
}

.projects-hero h1 {
  font-size: 3.5rem;
  margin-bottom: 1.5rem;
  font-weight: 600;
  text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
}

.hero-description {
  font-size: 1.25rem;
  color: rgba(255, 255, 255, 0.95);
  margin-bottom: 2rem;
  line-height: 1.6;
}

.projects-content {
  padding: 4rem 2rem;
  background-color: #1a1a1a;
  min-height: 60vh;
}

.content-wrapper {
  max-width: 1200px;
  margin: 0 auto;
}

.filters {
  margin-bottom: 3rem;
  display: flex;
  gap: 2rem;
  align-items: center;
  flex-wrap: wrap;
}

.search-box {
  flex: 1;
  min-width: 300px;
}

.search-input {
  width: 100%;
  padding: 0.8rem 1.2rem;
  border: 2px solid rgba(255, 255, 255, 0.1);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.05);
  color: #ffffff;
  font-size: 1rem;
  transition: all 0.3s ease;
}

.search-input:focus {
  outline: none;
  border-color: #7b82ff;
  background: rgba(255, 255, 255, 0.1);
}

.search-input::placeholder {
  color: rgba(255, 255, 255, 0.5);
}

.filter-options {
  display: flex;
  gap: 1rem;
}

.filter-select {
  padding: 0.8rem 1.2rem;
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 12px;
  background: rgba(40, 40, 45, 0.8);
  color: rgba(255, 255, 255, 0.9);
  font-size: 0.95rem;
  cursor: pointer;
  transition: all 0.3s ease;
  min-width: 140px;
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='rgba(255,255,255,0.5)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 12px center;
  background-size: 16px;
  padding-right: 40px;
  backdrop-filter: blur(12px);
}

.filter-select:hover {
  background-color: rgba(45, 45, 50, 0.9);
  border-color: rgba(123, 130, 255, 0.15);
}

.filter-select:focus {
  outline: none;
  border-color: rgba(123, 130, 255, 0.5);
  background-color: rgba(45, 45, 50, 0.95);
  box-shadow: 0 0 0 3px rgba(123, 130, 255, 0.1);
}

.projects-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 2rem;
}

.project-card {
  border-radius: 16px;
  transition: all 0.3s ease;
  height: 100%;
  display: flex;
  flex-direction: column;
}

.project-card:hover {
  transform: translateY(-5px);
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);
}

.project-header {
  display: flex;
  gap: 1rem;
  margin-bottom: 1.5rem;
  flex-wrap: wrap;
}

.project-card h3 {
  font-size: 1.5rem;
  color: #ffffff;
  margin-bottom: 1rem;
  line-height: 1.4;
  font-weight: 600;
}

.project-description {
  color: rgba(255, 255, 255, 0.85);
  line-height: 1.6;
  margin-bottom: 1.5rem;
  flex-grow: 1;
}

.project-tags {
  margin-bottom: 1.5rem;
}

.project-stats {
  display: flex;
  justify-content: space-between;
  margin: 1rem 0;
  padding: 0.5rem;
  background: rgba(255, 255, 255, 0.03);
  border-radius: 8px;
}

.stat-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.25rem;
}

.stat-label {
  font-size: 0.85rem;
  color: rgba(255, 255, 255, 0.5);
}

.stat-value {
  font-size: 1.1rem;
  font-weight: 500;
  color: rgba(255, 255, 255, 0.9);
}

.rating-display {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.rating-value {
  font-size: 0.9rem;
  color: rgba(255, 255, 255, 0.9);
}

.project-actions {
  display: flex;
  gap: 1rem;
  margin: 1rem 0;
}

.project-meta {
  display: flex;
  justify-content: space-between;
  align-items: center;
  color: rgba(255, 255, 255, 0.6);
  font-size: 0.9rem;
  border-top: 1px solid rgba(255, 255, 255, 0.1);
  padding-top: 1rem;
}

.meta-info {
  display: flex;
  gap: 1.5rem;
  flex-wrap: wrap;
}

.meta-item {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  white-space: nowrap;
}

.meta-label {
  color: rgba(255, 255, 255, 0.4);
}

.rating-modal {
  padding: 1rem 0;
}

.rating-form {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
  margin: 1.5rem 0;
}

.rating-field {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.rating-field label {
  font-size: 0.95rem;
  color: rgba(255, 255, 255, 0.9);
}

.modal-footer {
  display: flex;
  justify-content: flex-end;
  gap: 1rem;
  margin-top: 2rem;
}

.sort-select {
  min-width: 120px;
}

@media (max-width: 768px) {
  .projects-hero {
    padding: 6rem 1rem 3rem;
  }

  .projects-hero h1 {
    font-size: 2.5rem;
  }

  .hero-description {
    font-size: 1.1rem;
  }

  .projects-content {
    padding: 2rem 1rem;
  }

  .filters {
    flex-direction: column;
    gap: 1rem;
  }

  .search-box {
    min-width: 100%;
  }

  .filter-options {
    width: 100%;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.75rem;
  }

  .filter-select {
    width: 100%;
    min-width: 0;
    font-size: 0.9rem;
    padding: 0.7rem 1rem;
    padding-right: 32px;
  }

  .projects-grid {
    grid-template-columns: 1fr;
  }

  .project-meta {
    flex-direction: row;
    gap: 1rem;
    width: 100%;
    justify-content: space-between;
  }

  .meta-info {
    flex-direction: row;
    gap: 1rem;
    width: 100%;
    justify-content: space-between;
  }

  .project-stats {
    flex-direction: row;
    padding: 0.75rem;
  }

  .project-actions {
    flex-direction: row;
    justify-content: space-between;
  }
}

@media (min-width: 769px) and (max-width: 1024px) {
  .projects-hero h1 {
    font-size: 3rem;
  }

  .projects-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}
</style> 